import subprocess
import time
import re
from rapidfuzz import fuzz, utils
from tkinter import S
from seleniumbase import SB
from random import random, randrange

from scaner.core.config.log_config import MyLogger
from .selectors import selectors
from ..schemas import ADSDataBase


main_logger = MyLogger()


class ADSScrapper:
    sleep: int = 15
    ads: list[ADSDataBase] = []

    def __init__(
        self,
        rubric_url: str,
        query_string: str,
        deep_pages: int = 1,
        city: str = "all",
        main_url: str = "https://www.avito.ru/",
    ) -> None:

        self.logger = main_logger.getChild("scraping ads")  # type: ignore
        self.rubric_url = rubric_url
        self.query_string = self.__get_query_string(query_string)
        self.deep_pages = deep_pages
        self.city = city
        self.main_url = main_url

    def start_scrapping(self) -> None:
        for page in range(1, self.deep_pages + 1):
            full_search_url = self.__get_full_url(page)
            self.__get_page(full_search_url)
            time.sleep(self.sleep)

    def get_ads_data(self) -> list[ADSDataBase]:
        return self.ads

    def __get_page(self, url: str) -> None:
        self.logger.info(f"Загрузка старицы {url}")

        with SB(
            browser="chrome",
            uc=True,
            uc_subprocess=False,
            headed=True,
            headless=True,
            page_load_strategy="eager",
            block_images=True,
        ) as self.sb:
            try:
                self.sb.driver.uc_open_with_reconnect(url, 5)
                time.sleep(self.sleep + self.sleep * random())

                if "Доступ ограничен" in self.sb.get_title():
                    raise Exception("Блокировка IP")

                self.__parse_page()

            except Exception as e:
                self.logger.error(f"Ошибка загрузки страницы: {e}")

    def __get_full_url(self, page: int = 1) -> str:

        # https://www.avito.ru/ kurgan / remont_i_stroitelstvo ?cd=1 &q=металлолом+бу &s=104

        return f"{self.main_url}{self.city}{self.rubric_url}?cd=1&p={page}&q={self.query_string}"

    @staticmethod
    def __get_query_string(search_string: str) -> str:
        return re.sub(" ", "+", search_string)

    def __parse_page(self) -> None:

        try:
            items = self.sb.find_elements(selectors.item, by="css selector")
        except Exception as e:
            self.logger.error(f"Данные не найдены, {e}")
            return

        for item in items:
            try:
                url = item.find_element(*selectors.url).get_attribute("href")

                if url in [i.url for i in self.ads]:
                    continue

                ads_data = ADSDataBase(
                    title=item.find_element(*selectors.title).text,
                    price=item.find_element(*selectors.price).get_attribute("content"),
                    currency=item.find_element(*selectors.currency).get_attribute(
                        "content"
                    ),
                    descriptions=item.find_element(*selectors.descriptions).text,
                    url=url,
                    data_marker=item.find_element(*selectors.data_marker).text,
                )

                if self.__check_content(ads_data.title):
                    self.ads.append(ads_data)

            except Exception as e:
                self.logger.error("Ошибка получения данных")
                break

    def __check_content(self, title: str) -> bool:
        similarity = fuzz.partial_ratio(
            s1=self.query_string,
            s2=title,
            processor=utils.default_process,
        )
        return True if similarity > 40 else False
